package com.clp.protocol.modbus_tcp.mb_frame;

import com.clp.protocol.core.utils.ByteUtil;
import com.clp.protocol.modbus_tcp.definition.ConstVal;
import com.clp.protocol.modbus_tcp.definition.MbFrmType;
import com.clp.protocol.modbus_tcp.definition.MbByteOrder;
import com.clp.protocol.modbus_tcp.mb_frame.mb_head.MbHead;

import java.nio.ByteOrder;

public interface MbFrm extends InitializableFrame<MbFrm> {
    MbFrmType mbFrmType();

    MbHead getHead();

    default boolean isReqType() {
        return mbFrmType() == MbFrmType.REQ;
    }

    default boolean isRespType() {
        return isRespOKType() || isRespErrType();
    }

    default boolean isRespOKType() {
        return mbFrmType() == MbFrmType.RESP_OK;
    }

    default boolean isRespErrType() {
        return mbFrmType() == MbFrmType.RESP_ERR;
    }

    default ReqMbFrm castToReqType() {
        if (!this.isReqType()) throw new RuntimeException("类型转换失败！");
        return ((ReqMbFrm) this);
    }

    default RespMbFrm castToRespType() {
        if (!this.isRespType()) throw new RuntimeException("类型转换失败！");
        return ((RespMbFrm) this);
    }

    default RespOkMbFrm castToRespOkType() {
        if (!this.isRespOKType()) throw new RuntimeException("类型转换失败！");
        return ((RespOkMbFrm) this);
    }

    default RespErrMbFrm castToRespErrType() {
        if (!this.isRespErrType()) throw new RuntimeException("类型转换失败！");
        return ((RespErrMbFrm) this);
    }

    @Override
    default byte[] toByteArray() {
        byte[] retBytes = InitializableFrame.super.toByteArray();
        // 注意：最后要设置长度
        int len = retBytes.length - ConstVal.SEQ_LEN - ConstVal.TAG_LEN - ConstVal.LEN_LEN;
        byte[] fixBytes = MbByteOrder.lenOrder == ByteOrder.BIG_ENDIAN ?
                ByteUtil.intToBytes2BE(len) : ByteUtil.intToBytes2LE(len);
        retBytes[4] = fixBytes[0];
        retBytes[5] = fixBytes[1];
        return retBytes;
    }
}
